package diploma.kisel.modelas.gui;

import static diploma.kisel.modelas.service.StaticHelper.nullToEmptyString;

import java.awt.BorderLayout;
import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;
import javax.swing.JOptionPane;
import javax.swing.ListSelectionModel;
import javax.swing.SpringLayout;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.JTextArea;
import javax.swing.JScrollPane;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.Vector;

import javax.swing.JTable;

import diploma.kisel.modelas.domain.Computer;
import diploma.kisel.modelas.domain.ComputerType;
import diploma.kisel.modelas.domain.Concept;
import diploma.kisel.modelas.domain.Database;
import diploma.kisel.modelas.domain.DatabaseType;
import diploma.kisel.modelas.domain.Device;
import diploma.kisel.modelas.domain.Workstation;
import diploma.kisel.modelas.domain.WorkstationType;
import diploma.kisel.modelas.gui.common.CurrentVar;
import diploma.kisel.modelas.gui.common.TablesService;
import diploma.kisel.modelas.gui.common.TablesSettings;
import diploma.kisel.modelas.service.ComputerServiceImpl;
import diploma.kisel.modelas.service.ConceptServiceImpl;
import diploma.kisel.modelas.service.DatabaseServiceImpl;
import diploma.kisel.modelas.service.StaticHelper;
import diploma.kisel.modelas.service.WorkstationServiceImpl;
import diploma.kisel.modelas.service.api.ComputerService;
import diploma.kisel.modelas.service.api.ConceptService;
import diploma.kisel.modelas.service.api.DatabaseService;
import diploma.kisel.modelas.service.api.WorkplaceService;
import diploma.kisel.modelas.service.api.WorkstationService;

/**
 * This window is used to described and saved new server.
 * 
 * @author Nikolay Kisel
 *
 */
public class ServerWindow extends JFrame {

	private JPanel contentPane;
	private JTextArea textArea;
	private JTable tablePC;
	private JTable tableDevice;

	private static DefaultTableModel model;
	private static Vector<Vector<Object>> tableDataPC;
	private static Vector<Vector<Object>> tableDataDevice;

	private int rowPC;
	private int rowDevice;
	private int rowDatabase;

	private Set<Computer> computers = new HashSet<Computer>();
	private Set<Device> devices = new HashSet<Device>();
	private Set<Database> databases = new HashSet<Database>();

	private WorkstationService workstationService = new WorkstationServiceImpl();
	// ******************need to change*********************************
	private ConceptService conceptService = new ConceptServiceImpl();
	private DatabaseService databaseService = new DatabaseServiceImpl();

	// private Concept currConcept = conceptService.findById(1);
	// *****************************************************************
	private Concept currConcept = CurrentVar.getCurrentConcept();

	private static ServerWindow frame;
	private JTable tableDatabase;
	
	private ComputerService computerService = new ComputerServiceImpl();

	/**
	 * Create the frame.
	 */
	public ServerWindow() {
		setTitle("Добавление сервера");
		// setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 499, 545);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		setContentPane(contentPane);
		SpringLayout sl_contentPane = new SpringLayout();
		contentPane.setLayout(sl_contentPane);

		JLabel label_1 = new JLabel("Названия:");
		sl_contentPane.putConstraint(SpringLayout.NORTH, label_1, 3,
				SpringLayout.NORTH, contentPane);
		contentPane.add(label_1);

		JScrollPane scrollPane = new JScrollPane();
		sl_contentPane.putConstraint(SpringLayout.NORTH, scrollPane, -1,
				SpringLayout.NORTH, label_1);
		sl_contentPane.putConstraint(SpringLayout.WEST, scrollPane, 28,
				SpringLayout.EAST, label_1);
		sl_contentPane.putConstraint(SpringLayout.EAST, scrollPane, -197,
				SpringLayout.EAST, contentPane);
		contentPane.add(scrollPane);

		textArea = new JTextArea();
		scrollPane.setViewportView(textArea);

		JLabel label_2 = new JLabel("Добавить ПЭВМ:");
		sl_contentPane.putConstraint(SpringLayout.WEST, label_1, 0,
				SpringLayout.WEST, label_2);
		sl_contentPane.putConstraint(SpringLayout.NORTH, label_2, 75,
				SpringLayout.NORTH, contentPane);
		sl_contentPane.putConstraint(SpringLayout.WEST, label_2, 10,
				SpringLayout.WEST, contentPane);
		contentPane.add(label_2);

		JButton btnAddPC = new JButton("Добавить");
		sl_contentPane.putConstraint(SpringLayout.SOUTH, scrollPane, -6,
				SpringLayout.NORTH, btnAddPC);
		sl_contentPane.putConstraint(SpringLayout.NORTH, btnAddPC, -4,
				SpringLayout.NORTH, label_2);
		sl_contentPane.putConstraint(SpringLayout.WEST, btnAddPC, 52,
				SpringLayout.EAST, label_2);
		btnAddPC.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				addPC();
			}
		});
		contentPane.add(btnAddPC);

		JScrollPane scrollPane_1 = new JScrollPane();
		sl_contentPane.putConstraint(SpringLayout.WEST, scrollPane_1, 10,
				SpringLayout.WEST, contentPane);
		sl_contentPane.putConstraint(SpringLayout.EAST, scrollPane_1, -11,
				SpringLayout.EAST, contentPane);
		sl_contentPane.putConstraint(SpringLayout.NORTH, scrollPane_1, 6,
				SpringLayout.SOUTH, btnAddPC);
		contentPane.add(scrollPane_1);

		tablePC = new JTable(TablesSettings.modelSettingForPC(model, computers));
		scrollPane_1.setViewportView(tablePC);
		TableColumn col = tablePC.getColumnModel().getColumn(0);
		col.setMinWidth(0);
		col.setMaxWidth(0);

		tablePC.addMouseListener(new MouseAdapter() {
			public void mouseClicked(MouseEvent e) {
				if (e.getButton() == MouseEvent.BUTTON3) {
					if (rowPC >= 0) {
						int response = JOptionPane.showConfirmDialog(frame,
								"Удалить выделенную строку?");

						if (response == JOptionPane.YES_OPTION) {
							Computer computer = TablesService.getPCFromTable(
									tablePC, rowPC);
							computers.remove(computer);
							rowPC = -1;
							updateModelForPC();
						}
					}
				}
			}
		});

		ListSelectionModel listSelModPC = tablePC.getSelectionModel();
		listSelModPC.addListSelectionListener(new ListSelectionListener() {

			@Override
			public void valueChanged(ListSelectionEvent e) {
				rowPC = tablePC.getSelectedRow();
			}
		});

		JLabel label_3 = new JLabel("Добавить устройства:");
		sl_contentPane.putConstraint(SpringLayout.NORTH, label_3, 205,
				SpringLayout.NORTH, contentPane);
		sl_contentPane.putConstraint(SpringLayout.WEST, label_3, 10,
				SpringLayout.WEST, contentPane);
		sl_contentPane.putConstraint(SpringLayout.SOUTH, scrollPane_1, -25,
				SpringLayout.NORTH, label_3);
		contentPane.add(label_3);

		JButton btnAddDevice = new JButton("Добавить");
		btnAddDevice.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				addDevice();
			}
		});
		sl_contentPane.putConstraint(SpringLayout.NORTH, btnAddDevice, -4,
				SpringLayout.NORTH, label_3);
		sl_contentPane.putConstraint(SpringLayout.WEST, btnAddDevice, 0,
				SpringLayout.WEST, btnAddPC);
		contentPane.add(btnAddDevice);

		JScrollPane scrollPane_2 = new JScrollPane();
		sl_contentPane.putConstraint(SpringLayout.NORTH, scrollPane_2, 6,
				SpringLayout.SOUTH, btnAddDevice);
		sl_contentPane.putConstraint(SpringLayout.WEST, scrollPane_2, 10,
				SpringLayout.WEST, contentPane);
		sl_contentPane.putConstraint(SpringLayout.SOUTH, scrollPane_2, 93,
				SpringLayout.SOUTH, btnAddDevice);
		sl_contentPane.putConstraint(SpringLayout.EAST, scrollPane_2, -11, SpringLayout.EAST, contentPane);
		contentPane.add(scrollPane_2);

		tableDevice = new JTable(TablesSettings.modelSettingForDevice(model,
				devices));
		scrollPane_2.setViewportView(tableDevice);
		col = tableDevice.getColumnModel().getColumn(0);
		col.setMinWidth(0);
		col.setMaxWidth(0);

		tableDevice.addMouseListener(new MouseAdapter() {
			public void mouseClicked(MouseEvent e) {
				if (e.getButton() == MouseEvent.BUTTON3) {
					if (rowDevice >= 0) {
						int response = JOptionPane.showConfirmDialog(frame,
								"Удалить выделенную строку?");

						if (response == JOptionPane.YES_OPTION) {
							Device device = TablesService.getDeviceFromTable(
									tableDevice, rowDevice);
							devices.remove(device);
							rowDevice = -1;
							updateModelForDevice();
						}
					}
				}
			}
		});

		ListSelectionModel listSelModDevice = tableDevice.getSelectionModel();
		listSelModDevice.addListSelectionListener(new ListSelectionListener() {

			@Override
			public void valueChanged(ListSelectionEvent e) {
				rowDevice = tableDevice.getSelectedRow();
			}
		});

		JButton btnCancel = new JButton("Отменить");
		btnCancel.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				frame.setVisible(false);
			}
		});
		sl_contentPane.putConstraint(SpringLayout.SOUTH, btnCancel, 0,
				SpringLayout.SOUTH, contentPane);
		sl_contentPane.putConstraint(SpringLayout.EAST, btnCancel, -10,
				SpringLayout.EAST, contentPane);
		contentPane.add(btnCancel);

		JButton btnSave = new JButton("Сохранить");
		btnSave.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				saveServer();
			}
		});
		sl_contentPane.putConstraint(SpringLayout.SOUTH, btnSave, 0,
				SpringLayout.SOUTH, btnCancel);
		sl_contentPane.putConstraint(SpringLayout.EAST, btnSave, -6,
				SpringLayout.WEST, btnCancel);
		contentPane.add(btnSave);

		JLabel label = new JLabel("Добавить общую бд:");
		sl_contentPane.putConstraint(SpringLayout.NORTH, label, 22, SpringLayout.SOUTH, scrollPane_2);
		sl_contentPane.putConstraint(SpringLayout.WEST, label, 0,
				SpringLayout.WEST, label_1);
		contentPane.add(label);

		JButton btnAddDB = new JButton("Добавить");
		btnAddDB.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				addDatabase();
			}
		});
		sl_contentPane.putConstraint(SpringLayout.NORTH, btnAddDB, -4,
				SpringLayout.NORTH, label);
		sl_contentPane.putConstraint(SpringLayout.WEST, btnAddDB, 0,
				SpringLayout.WEST, btnAddPC);
		contentPane.add(btnAddDB);

		JScrollPane scrollPane_3 = new JScrollPane();
		sl_contentPane.putConstraint(SpringLayout.NORTH, scrollPane_3, 6,
				SpringLayout.SOUTH, btnAddDB);
		sl_contentPane.putConstraint(SpringLayout.WEST, scrollPane_3, 0,
				SpringLayout.WEST, label_1);
		sl_contentPane.putConstraint(SpringLayout.SOUTH, scrollPane_3, 91,
				SpringLayout.SOUTH, label);
		sl_contentPane.putConstraint(SpringLayout.EAST, scrollPane_3, -11, SpringLayout.EAST, contentPane);
		contentPane.add(scrollPane_3);

		tableDatabase = new JTable(TablesSettings.modelSettingForDatabase(
				model, databases));
		scrollPane_3.setViewportView(tableDatabase);
		TablesSettings.makeFirstColumnInvisible(tableDatabase);
		
		tableDatabase.addMouseListener(new MouseAdapter() {
			public void mouseClicked(MouseEvent e) {
				if (e.getButton() == MouseEvent.BUTTON3) {
					if (rowDatabase >= 0) {
						int response = JOptionPane.showConfirmDialog(frame,
								"Удалить выделенную строку?");

						if (response == JOptionPane.YES_OPTION) {
							Database database = TablesService.getDatabaseFromTable(
									tableDatabase, rowDatabase);
							databases.remove(database);
							rowDatabase = -1;
							updateModelForDatabase();
						}
					}
				}
			}
		});

		ListSelectionModel listSelModDatabase = tableDatabase.getSelectionModel();
		listSelModDatabase.addListSelectionListener(new ListSelectionListener() {

			@Override
			public void valueChanged(ListSelectionEvent e) {
				rowDatabase = tableDatabase.getSelectedRow();
			}
		});
	}

	public void addPC() {
		ComputerCatalogWindow computerCatalogWindow = new ComputerCatalogWindow();
		ComputerCatalogWindow.setFrame(computerCatalogWindow);
		computerCatalogWindow.setFromServerWindow(true);
		computerCatalogWindow.setCurrServerWindow(this);
		ComputerCatalogWindow.setNewModel(computerService.findByType(ComputerType.Server));
		computerCatalogWindow.setVisible(true);
	}

	public void addDevice() {
		DeviceCatalogWindow deviceCatalogWindow = new DeviceCatalogWindow();
		DeviceCatalogWindow.setFrame(deviceCatalogWindow);
		deviceCatalogWindow.setFromServerWindow(true);
		deviceCatalogWindow.setCurrServerWindow(this);
		deviceCatalogWindow.setVisible(true);
	}

	public void addDatabase() {
		DatabaseWindow databaseWindow = new DatabaseWindow();
		DatabaseWindow.setFrame(databaseWindow);
		databaseWindow.setCurrentServerWindow(this);
		databaseWindow.setVisible(true);
	}

	public void setNewModelForPC(Computer computer) {
		computers.add(computer);
		updateModelForPC();
	}

	public void updateModelForPC() {
		tablePC.setModel(TablesSettings.modelSettingForPC(model, computers));
		makeFirstColumnInvisible(tablePC);
	}

	public void setNewModelForDevice(Device device) {
		devices.add(device);
		updateModelForDevice();
	}

	public void updateModelForDevice() {
		tableDevice.setModel(TablesSettings.modelSettingForDevice(model,
				devices));
		makeFirstColumnInvisible(tableDevice);
	}

	public void setNewModelForDatabase(Database database) {
		databases.add(database);
		updateModelForDatabase();
	}

	public void updateModelForDatabase() {
		tableDatabase.setModel(TablesSettings.modelSettingForDatabase(model,
				databases));
		makeFirstColumnInvisible(tableDatabase);
	}

	public void makeFirstColumnInvisible(JTable table) {
		TableColumn col = table.getColumnModel().getColumn(0);
		col.setMinWidth(0);
		col.setMaxWidth(0);
	}

	public void saveServer() {
		String text = textArea.getText();
		String[] names = StaticHelper.getWords(text, ",");
		List<Workstation> workstations = new ArrayList<Workstation>();
		for (Database database : databases) {
			database.setType(DatabaseType.Common);
			databaseService.save(database);
		}
		for (int i = 0; i < names.length; i++) {
			Workstation workstation = new Workstation(names[i],
					WorkstationType.Server);
			workstation.setComputers(computers);
			workstation.setDevices(devices);
			workstation.setCommonDatabases(databases);
			workstation.setConcept(currConcept);
			workstations.add(workstation);
		}

		for (int i = 0; i < workstations.size(); i++)
			workstationService.save(workstations.get(i));

		JOptionPane.showMessageDialog(frame, "Серверы сохранены.");
		setVisible(false);
		//openWorkplaceWindow();

	}

	public static ServerWindow getFrame() {
		return frame;
	}

	public static void setFrame(ServerWindow frame) {
		ServerWindow.frame = frame;
	}

	public void openWorkplaceWindow() {
		WorkplaceWindow workplaceWindow = new WorkplaceWindow();
		WorkplaceWindow.setFrame(workplaceWindow);
		workplaceWindow.setVisible(true);
	}
}
